home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Sockets routines to handle socket io of objects. *
- * *
- * Written by: Gershon Elber Ver 0.1, June 1993. *
- *****************************************************************************/
-
- #include <stdio.h>
- #include <sys/types.h>
-
- #ifdef __UNIX__
- #if (defined(ultrix) && defined(mips)) || defined(_AIX) || defined(sgi)
- # include <fcntl.h>
- #else
- # include <sys/fcntl.h>
- #endif /* (ultrix && mips) || _AIX || sgi */
- #if defined(__hpux)
- # include <sys/file.h>
- #endif /* __hpux */
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <errno.h>
- #endif /* __UNIX__ */
-
- #ifdef OS2GCC
- # include <os2.h>
- HFILE IritPipe;
- #endif /* OS2GCC */
-
- #ifdef __WINNT__
- #include <stdlib.h>
- #include <windows.h>
- #include <winsock.h>
- #include <io.h>
- #endif /* __WINNT__ */
-
- #include "irit_sm.h"
- #include "irit_soc.h"
-
- /* #define DEBUG_ECHO */
-
- static char
- GlblClientUnReadChar = 0;
-
- static int
- GlblBinaryIPC = FALSE,
- GlblEchoInput = FALSE,
- GlblCommuSoc = 0;
-
- static void SocketPrintError(char *Str);
- static int SocReadObjPrefix(void);
-
- /*****************************************************************************
- * IO error print routine. *
- *****************************************************************************/
- static void SocketPrintError(char *Str)
- {
- # if defined(__UNIX__) || defined(OS2GCC)
- perror(Str);
- # endif /* __UNIX__ || OS2GCC */
- # ifdef __WINNT__
- fprintf(stderr, "iritserver: %s error %d\n", Str, WSAGetLastError());
- # endif /* __WINNT__ */
- }
-
- /*****************************************************************************
- * Set echo printing of read input. *
- *****************************************************************************/
- void SocClientEchoInput(int EchoInput)
- {
- GlblEchoInput = EchoInput;
- }
-
- /*****************************************************************************
- * Non blocking read of a single char. Returns EOF if no data is found. *
- *****************************************************************************/
- int SocClientReadCharNonBlock(void)
- {
- int c;
- static unsigned char Buffer[LINE_LEN_LONG];
- static int
- BufferSize = 0,
- BufferPtr = 0;
-
- if (GlblClientUnReadChar != 0) {
- c = GlblClientUnReadChar;
- GlblClientUnReadChar = 0;
- return c;
- }
- else if (BufferPtr < BufferSize) {
- c = Buffer[BufferPtr++];
- return c;
- }
-
- #ifdef OS2GCC
- DosRead(IritPipe, Buffer, LINE_LEN_LONG, (PULONG) &BufferSize);
- #endif /* OS2GCC */
- #if defined(__UNIX__) || defined(__WINNT__)
- BufferSize = recv(GlblCommuSoc, Buffer, LINE_LEN_LONG, 0);
- #endif /* __UNIX__ || __WINNT__ */
-
- if (BufferSize > 0) {
- if (GlblEchoInput) {
- int i;
- unsigned char
- *p = Buffer;
-
- if (GlblBinaryIPC) {
- for (i = 0; i < BufferSize; i++) {
- if (i % 16 == 0)
- printf("\n%04x: ", i);
- printf("%02x ", *p++);
- }
- printf("\n");
- }
- else
- for (i = 0; i < BufferSize; i++)
- putc(*p++, stdout);
- }
- BufferPtr = 0;
- c = Buffer[BufferPtr++];
- }
- else
- c = EOF;
-
- return c;
- }
-
- /*****************************************************************************
- * Unget one char from client socket. *
- *****************************************************************************/
- void SocClientUnReadChar(char c)
- {
- GlblClientUnReadChar = c;
- }
-
- /*****************************************************************************
- * Get a single line for syncronization purposes that will prefix an object. *
- * Returns TRUE if prefix found, FALSE otherwise. *
- *****************************************************************************/
- static int SocReadObjPrefix(void)
- {
- if (GlblBinaryIPC) {
- int c;
-
- if ((c = SocClientReadCharNonBlock()) != EOF) {
- SocClientUnReadChar(c);
- return TRUE;
- }
- }
- else {
- if (SocClientReadCharNonBlock() == '[') {
- SocClientUnReadChar('[');
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
- /*****************************************************************************
- * Non blocking read of a single line. Returns NULL if no line is available. *
- *****************************************************************************/
- char *SocClientReadLineNonBlock(void)
- {
- static char Line[LINE_LEN_LONG];
- static int
- LineLen = 0;
-
- while (TRUE) {
- int c;
-
- if ((c = SocClientReadCharNonBlock()) != EOF) {
- if (c == '\n' || c == '\r') {
- Line[LineLen++] = c;
- Line[LineLen] = 0;
-
- LineLen = 0;
- return Line;
- }
- else if (LineLen >= LINE_LEN_LONG - 1) {
- IritPrsrFatalError("Socket read line too long\n");
- exit(1);
- }
- else {
- Line[LineLen++] = c;
- }
- }
- else
- return NULL;
- }
- }
-
- /*****************************************************************************
- * Creates a client socket. Returns TRUE if succesful. *
- *****************************************************************************/
- int SocClientCreateSocket(void)
- {
- #if defined(__UNIX__) || defined(__WINNT__)
- int s;
- char *hostname, *portnum, hostnamestr[LINE_LEN];
- struct sockaddr_in sain;
- struct hostent *host;
- struct servent *serv;
-
- GlblCommuSoc = 0;
-
- #ifdef __WINNT__
- {
- WSADATA WSAData;
-
- if ((s = WSAStartup(MAKEWORD(1, 1), &WSAData)) != 0) {
- fprintf(stderr, "iritserver: WSAStartup: error %d\n",
- WSAGetLastError());
- exit(1);
- }
- }
- #endif
-
- /* Get port address. */
- gethostname(hostnamestr, LINE_LEN);
- if ((hostname = getenv("IRIT_SERVER_HOST")) == NULL)
- hostname = hostnamestr;
-
- if ((host = gethostbyname(hostname)) == NULL) {
- SocketPrintError("iritclient: hostname unknown\n");
- return FALSE;
- }
-
- ZAP_MEM(&sain, sizeof(struct sockaddr_in));
- GEN_COPY(&sain.sin_addr, host -> h_addr_list[0], host -> h_length);
- sain.sin_family = AF_INET;
-
- if ((portnum = getenv("IRIT_SERVER_PORT")) != NULL)
- sain.sin_port = atoi(portnum);
- else if ((serv = getservbyname(IRIT_TCP_SERVICE, "tcp")) == NULL)
- sain.sin_port = htons(IRIT_TCP_PORT);
- else
- sain.sin_port = serv->s_port;
-
- /* Create the socket, make it nonblocking and connect. */
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- SocketPrintError("iritclient: socket");
- return FALSE;
- }
-
- #ifdef __UNIX__
- #ifdef __hpux
- if (fcntl(s, F_SETFL, O_NDELAY) < 0) {
- #else
- if (fcntl(s, F_SETFL, FNDELAY) < 0) {
- #endif /* __hpux */
- SocketPrintError("iritclient: fcntl");
- return FALSE;
- }
- #endif /* __UNIX__ */
-
- while (connect(s, (struct sockaddr *) &sain,
- sizeof(struct sockaddr_in)) < 0) {
- # ifdef __UNIX__
- if (errno == EINPROGRESS)
- break;
- # endif /* __UNIX__ */
- # ifdef __WINNT__
- if (WSAGetLastError() == WSAEINPROGRESS)
- break;
- # endif /* __WINNT__ */
- SocketPrintError("iritclient: connect");
- return FALSE;
- }
-
- GlblCommuSoc = s;
- #endif /* __UNIX__ || __WINNT__ */
-
- #ifdef OS2GCC
- ULONG rc,
- ulActionTaken, ulFileSize, ulFileAttribute, ulOpenFlag, ulOpenMode;
-
- DosWaitNPipe(IRIT_PIPE, NP_WAIT);
- ulFileSize = 0;
- ulFileAttribute = 0;
- ulOpenFlag = OPEN_ACTION_OPEN_IF_EXISTS;
- ulOpenMode = OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE;
- rc = DosOpen(IRIT_PIPE,
- &IritPipe,
- &ulActionTaken,
- ulFileSize,
- ulFileAttribute,
- ulOpenFlag,
- ulOpenMode,
- NULL);
-
- if (rc != 0) {
- DosBeep(1000, 100);
- exit(1);
- }
-
- GlblCommuSoc = 1;
- #endif /* OS2GCC */
-
- GlblBinaryIPC = getenv("IRIT_BIN_IPC") != NULL;
-
- return TRUE;
- }
-
- /*****************************************************************************
- * Close a client socket. *
- *****************************************************************************/
- void SocClientCloseSocket(void)
- {
- if (GlblCommuSoc > 0) {
- #ifdef __UNIX__
- if (close(GlblCommuSoc) != 0)
- SocketPrintError("iritclient: close");
- #endif /* __UNIX__ */
- #ifdef __WINNT__
- closesocket(GlblCommuSoc);
- #endif /* __WINNT__ */
- #ifdef OS2GCC
- DosClose(IritPipe);
- #endif /* OS2GCC */
-
- GlblCommuSoc = 0;
- }
- }
-
- /*****************************************************************************
- * Attempt to read (non blocking) from socket an object. *
- * If read is successful the object is returned, otherwise NULL is returned. *
- *****************************************************************************/
- IPObjectStruct *SocClientReadOneObject(void)
- {
- char *ErrorMsg;
- IPObjectStruct *PObj;
-
- if (GlblCommuSoc > 0 && SocReadObjPrefix()) {
- IritPrsrSetReadOneObject(TRUE);
-
- IritPrsrReadSocket(TRUE);
- if (GlblBinaryIPC) {
- PObj = IritPrsrGetBinObject(NULL);
- }
- else {
- PObj = IritPrsrGetObjects(NULL);
- }
- IritPrsrReadSocket(FALSE);
- }
- else
- PObj = NULL;
-
- if (IritPrsrParseError(&ErrorMsg)) {
- fprintf(stderr, "Socket: %s\n", ErrorMsg);
- }
-
- return PObj;
- }
-